package com.tmt.annotation.parser;

import com.tmt.helper.StringHelper;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Optional;

/**
 * 该类用于读取枚举类型字段上的任意注解的属性值。
 * Created by ThreeManTeam on 2020/6/15.
 */
public class EnumAnnotationParserEx {

    public static <T extends Enum, K extends Annotation, M> M getPropertyValue(T enumValue,
                                                                               Class<K> annotationCls,
                                                                               String propertyName,
                                                                               Class<M> valueType) {
        Field target = getEnumField(enumValue.getClass(), enumValue.name());
        return _getPropertyValue(target, annotationCls, propertyName, valueType);
    }

    public static <T extends Enum, K extends Annotation> boolean hasAnnotation(T enumValue,
                                                                               Class<K> annotationCls) {
        try {
            Field target = getEnumField(enumValue.getClass(), enumValue.name());
            if (target != null) {
                K[] array = target.getAnnotationsByType(annotationCls);
                return array != null && array.length > 0;
            }
        } catch (Exception ex) {
        }
        return false;
    }


    /***************************************************************************************************/
    /**********************私有方法*********************************************************************/

    private static <T extends Enum> Field getEnumField(Class<T> enumClass, final String enumName) {
        Field[] fields = enumClass.getFields();
        Optional optional = Arrays.stream(fields).filter(x -> x.getName().equals(enumName)).findFirst();
        if (optional.isPresent()) {
            return (Field) optional.get();
        }
        return null;
    }

    private static <K extends Annotation, M> M _getPropertyValue(Field target, Class<K> annotationCls,
                                                                 String propertyName, Class<M> valueType) {
        try {
            if (target != null) {
                K[] array = target.getAnnotationsByType(annotationCls);
                if (array.length > 0) {
                    Method method = array[0].getClass().getMethod(propertyName, null);
                    Object obj = method.invoke(array[0], null);
                    return StringHelper.convertTo(obj, valueType);
                }
            }
        } catch (Exception ex) {
        }
        return null;
    }

}
